#include "sync.h"

int finddir(char *path)
{ //寻找是否存在文件夹
	DIR *dir;
	dir = opendir(path);
	if (dir == NULL)
		return 0;
	else
		return 1;
}

int find_file(char *path, char *filename)
{ //在B中寻找文件，非递归
	DIR *dir;
	int flag = 0;
	struct dirent *entry;
	dir = opendir(path);
	if (dir == NULL)
	{
		perror("fail to open dir ：find file");
		exit(-1);
	}
	while ((entry = readdir(dir)) != NULL)
	{
		if (strcmp(entry->d_name, filename) == 0)
		{
			flag = 1;
		}
	}
	closedir(dir);
	return flag;
}

int CompareFile(char *file_src, char *file_dest)
{ //比较文件函数 ，相等返回1，否则返回0
	FILE *pfile_src, *pfile_dest;
	int flag = 1;
	char file_src_str[MAXLEN];
	char file_dest_str[MAXLEN];
	pfile_src = fopen(file_src, "r");
	pfile_dest = fopen(file_dest, "r");
	do
	{
		fgets(file_src_str, MAXLEN, pfile_src);
		fgets(file_dest_str, MAXLEN, pfile_dest);
		if (strcmp(file_src_str, file_dest_str) != 0)
		{
			flag = 0;
			break;
		}
	} while (!feof(pfile_src) && !feof(pfile_dest)); // feof判断文件是否结尾 没有结尾则返回0
	fclose(pfile_src);
	fclose(pfile_dest);
	return flag;
}

void dir_traverse_child(char *src, char *dest)
{ //删除B目录中没有的文件和比较同名文件
	DIR *dir = opendir(src); //打开源目录
	struct dirent *entry1;
	char pathA[PATH_MAX] = {0}; //存放子目录的路径
	char pathB[PATH_MAX] = {0};
	if (dir == NULL)
	{
		perror("fail to open src:");
		exit(-1);
	}
	while (1)
	{
		entry1 = readdir(dir);
		if (entry1 == NULL)
			break;
		if ((strcmp(entry1->d_name, ".") == 0) || (strcmp(entry1->d_name, "..") == 0))
		{
			continue;
		}
		sprintf(pathA, "%s/%s", src, entry1->d_name);
		sprintf(pathB, "%s/%s", dest, entry1->d_name);
		//递归目录
		if (entry1->d_type & DT_DIR)
		{
			if (!finddir(pathB)) // B中不存在文件夹,则删除
			{
				char massage[1024] = {0};
				sprintf(massage, "rm -rf %s", pathA);
				system(massage);
				printf("删除 %s 目录成功！\n", pathA);
				sprintf(massage, "echo '删除 %s 目录成功！' >>log.txt", pathA); //写入log文件
				system(massage);
			}
			else
				dir_traverse_child(pathA, pathB);
		}
		else //文件
		{
			if (!find_file(dest, entry1->d_name)) //在B目录中查找文件，没找到，则删除A中的文件
			{
				if (remove(pathA) == -1)
				{
					perror("fail to remove");
					exit(-1);
				}
				else
				{
					char massage[1024] = {0};
					sprintf(massage, "echo '删除 %s 文件成功！' >>log.txt", pathA); //写入log文件
					system(massage);
					printf("删除 %s 成功！\n", pathA);
				}
			}
			else //存在同名文件，则比较两个文件
			{
				if (!CompareFile(pathA, pathB)) //文件不相同时,复制文件
				{
					char massage[1024] = {0};
					printf("\n");
					sprintf(massage, "cp -vp %s %s", pathB, pathA);
					system(massage);
					printf("%s文件同步成功！\n", pathB);
					sprintf(massage, "echo '%s 文件同步成功！' >>log.txt", pathB); //写入log文件
					system(massage);
				}
			}
		}
	}
	closedir(dir);
}

void dir_traverse_parrent(char *src, char *dest)
{ //复制B中存在而A中不存在的文件
	DIR *dir;
	dir = opendir(dest); //打开目标目录
	struct dirent *entry;
	char path1[PATH_MAX] = {0}; //存放子目录的路径
	char path2[PATH_MAX] = {0};
	if (dir == NULL)
	{
		perror("fail to open dest");
		exit(-1);
	}
	while (1)
	{
		entry = readdir(dir);
		if (entry == NULL)
			break;
		if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0))
		{
			continue;
		}
		sprintf(path1, "%s/%s", src, entry->d_name);  // dest子路径
		sprintf(path2, "%s/%s", dest, entry->d_name); // src 子路径
		//递归目录
		if (entry->d_type & DT_DIR)
		{
			if (!finddir(path1)) // A中不存在该目录则复制
			{
				char massage[1024] = {0};
				sprintf(massage, "cp -vrp %s %s", path2, path1);
				system(massage);
				printf("同步目录 %s 成功！\n", path2);
				sprintf(massage, "echo '同步目录 %s 成功！' >>log.txt", path2); //写入log文件
				system(massage);
			}
			dir_traverse_parrent(path1, path2);
		}
		else //文件
		{
			if (!find_file(src, entry->d_name)) //在A目录中查找文件，没找到，则复制到A中
			{
				char massage[1024] = {0};
				sprintf(massage, "cp -vp %s %s", path2, path1);
				system(massage);
				printf("%s文件同步成功！\n", path1);
				sprintf(massage, "echo '%s 文件同步成功' >>log.txt", path1); //写入log文件
				system(massage);
			}
		}
	}
	closedir(dir);
}

void Sync(char *src, char *dest)
{
	system("echo '------文件同步'>>log.txt");
	pid_t pid;
	pid = fork();
	if (pid < 0)
	{
		perror("fail to fork:");
		exit(-1);
	}
	else if (pid == 0)
	{ //子进程
		dir_traverse_child(src, dest);
		exit(0);
	}
	else
	{ //父进程
		wait(NULL);
		dir_traverse_parrent(src, dest);
	}
}

